package com.ucode.application.helper;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.ucode.application.security.CurrentLoginUserService;
import com.ucode.crm.dictionary.ModuleType;
import com.ucode.crm.dictionary.TeamUserPower;
import com.ucode.crm.mode.FollowupTeamUser;
import com.ucode.crm.service.FollowupTeamUserService;
import com.ucode.sys.helper.DataPermissionHelper;
import com.ucode.tool.base.ResultCodeEnum;
import com.ucode.tool.exception.UcodeServiceException;

import cn.hutool.core.collection.CollUtil;

/**
 * 数据校验器
 * @author: liliang
 * @date: 2020年3月10日 下午6:37:02
 */
@Component
public class CrmDataPermissionVerifier {
    
    @Autowired
    private DataPermissionHelper dataPermissionHelper;
    @Autowired
    private FollowupTeamUserService followTeamUserService;
    @Autowired
    private CurrentLoginUserService currentLoginUserService;
    
    /**
     * 获取当前用户在目标业务下可操作那些用户的数据
     * @author liliang
     * @date 2020年2月11日
     * @param userId 用户Id
     * @param moduleCode 业务模块代码
     * @param opt 操作类型:0->读操作，1->写操作
     * @return 返回null,则代表管理全部用户，反之则返回管理的目标用户(包含自己)
     */
    public List<Long> getCurrentUserManageUsers(String moduleCode,Integer opt){
        Long currentUserId = currentLoginUserService.getCurrentUserId();
        return getUserManageUsers(currentUserId, moduleCode, opt);
    }
    
    /**
     * 获取用户在目标业务下可操作那些用户的数据
     * @author liliang
     * @date 2020年2月11日
     * @param userId 用户Id
     * @param moduleCode 业务模块代码
     * @param opt 操作类型:0->读操作，1->写操作
     * @return 返回null,则代表管理全部用户，反之则返回管理的目标用户(包含自己)
     */
    public List<Long> getUserManageUsers(Long userId ,String moduleCode,Integer opt){
        return dataPermissionHelper.findUserManageUsers(userId, moduleCode, opt);
    }
    
    /**
     * 获取并校验当前用户在业务模块下,可查看那些用户的数据(列表数据)</br>
     * 1、当检索用户为空时,则返回当前用户管辖的用户集合</br>
     * 2、当检索用户不为空时,则判断检索用户中是否有不是当前用户管辖的用户,有则抛异常，反之返回检索用户
     * @author liliang
     * @date 2020年3月6日
     * @param moduleCode 业务模块代码
     * @param userIds 检索用户
     * @return 
     */
    public List<Long> getCheckCurrentUserManageUsersByRead(String moduleCode,List<Long> userIds){
        Long currentUserId = currentLoginUserService.getCurrentUserId();
        List<Long> currentUserManageUserIds = this.getUserManageUsers(currentUserId,moduleCode, 0);

        if(currentUserManageUserIds != null && currentUserManageUserIds.size() == 0){
            throw new UcodeServiceException(ResultCodeEnum.UN_DATA_PERMISSION);
        }
        
         //判断检索用户中是否有包含当前用户无权管辖的用户
        if(CollUtil.isNotEmpty(userIds) && CollUtil.isNotEmpty(currentUserManageUserIds) && !currentUserManageUserIds.containsAll(userIds)){
            throw new UcodeServiceException(ResultCodeEnum.UN_DATA_PERMISSION);
        }
        
        if(CollUtil.isEmpty(userIds)){
            userIds = currentUserManageUserIds;
        }
        
        return userIds;
    }
    
    /**
     * 获取当前用户对业务数据的操作权限(数据详情)
     * @author liliang
     * @date 2020年3月10日
     * @param moduleCode 业务模块代码
     * @param businessType 业务类型 
     * @param businessDataId 数据数据Id
     * @return 0->负责人1->读写2->只读
     */
    public Integer getCurrentUserPowerByBusinessData(String moduleCode,ModuleType moduleType,Long businessDataId){
        
        Integer power = null;
        Long currentUserId = currentLoginUserService.getCurrentUserId();
        //获取当前用户的读写权限
        List<FollowupTeamUser> teamUsers = followTeamUserService.findList(businessDataId, moduleType.code);
        List<Long> targetUsers = new ArrayList<Long>();
        if(CollUtil.isNotEmpty(teamUsers)){
            Long ownerUserId = null;
            for(FollowupTeamUser followTeamUser : teamUsers){
                //负责人Id
                if(TeamUserPower.owner.code == followTeamUser.getPower()){
                    ownerUserId = followTeamUser.getUserId();
                }
                //如果当前人是团队成员,并且有读写权限则直接返回
                if(followTeamUser.getUserId().equals(currentUserId) && 
                        TeamUserPower.read.code != (power = followTeamUser.getPower())){
                    continue;
                }
                targetUsers.add(followTeamUser.getUserId());
            }
            
            //如果不是团队成员,则判断读权限
            if(power == null){
                List<Long> currentUserManageUserIds = this.getUserManageUsers(currentUserId,moduleCode, 0);
                if(currentUserManageUserIds != null && !CollUtil.containsAny(currentUserManageUserIds, targetUsers)){
                    throw new UcodeServiceException(ResultCodeEnum.UN_DATA_PERMISSION);
                }
                power = TeamUserPower.read.code;
            }
            
            //如果当前团队角色只有读权限，则判断用户是否拥有写权限
            if(TeamUserPower.read.code == power.intValue()){
                List<Long> currentUserManageUserIds = this.getUserManageUsers(currentUserId,moduleCode, 1);
                if(currentUserManageUserIds == null || CollUtil.contains(currentUserManageUserIds, ownerUserId)){
                    power = TeamUserPower.readWrite.code;
                }
            }
        }
        return power;
    }
    
    public void checkCurrentUserWritePowerByBusinessData(String moduleCode,ModuleType moduleType,Long businessDataId,Long ownerUserId,String errorMsgTemplate, Object... errorMsgParams){
        //校验数据编辑权限
        Long currentUserId = currentLoginUserService.getCurrentUserId();
        FollowupTeamUser followTeamUser = followTeamUserService.find(businessDataId, moduleType.code, currentUserId);
        if(followTeamUser == null || TeamUserPower.read.code == followTeamUser.getPower().intValue()){
            List<Long> currentUserManageUserIds = this.getUserManageUsers(currentUserId,moduleCode, 1);
            if(currentUserManageUserIds != null && !CollUtil.contains(currentUserManageUserIds, ownerUserId)){
                throw new UcodeServiceException(ResultCodeEnum.UN_DATA_PERMISSION.code,errorMsgTemplate,errorMsgParams);
            }
        }
    }
    
    public void checkCurrentUserWritePowerByBusinessData(List<Long> currentUserManageUserIds,ModuleType moduleType,Long businessDataId,Long ownerUserId,String errorMsgTemplate, Object... errorMsgParams){
        //校验数据编辑权限
        Long currentUserId = currentLoginUserService.getCurrentUserId();
        FollowupTeamUser followTeamUser = followTeamUserService.find(businessDataId, moduleType.code, currentUserId);
        if(followTeamUser == null || TeamUserPower.read.code == followTeamUser.getPower().intValue()){
            if(currentUserManageUserIds != null && !CollUtil.contains(currentUserManageUserIds, ownerUserId)){
                throw new UcodeServiceException(ResultCodeEnum.UN_DATA_PERMISSION.code,errorMsgTemplate,errorMsgParams);
            }
        }
    }
    
    
    
    
    
}
